﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Ecommerce.Web.Code;
using System.Web.Services;
using Ecommerce.Model;
using Ecommerce.Pagamento.CartaoCredito;
using Ecommerce.Pagamento;
using System.Net;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;

namespace Ecommerce.Web
{
    public partial class FecharPedido : BasePage
    {
        public struct RetornoPagamento
        {
            public int numeroPedido;
            public int codigoErro;
            public string mensagemErro;
            public string codigoTipoPagamento;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                if (Carrinho.Instance.Frete.Equals(0))
                {
                    Response.Redirect("~/CarrinhoCompras.aspx");
                }

                if (Carrinho.Instance.IdentificadorEndereco.Equals(0))
                {
                    Response.Redirect("~/SelecionarEndereco.aspx");
                }

                if (Carrinho.Instance.FormaPagamento.Equals(0))
                {
                    Response.Redirect("~/FormaPagamento.aspx");
                }
            }
        }

        [WebMethod]
        public static RetornoPagamento EfetuarPagamento()
        {
            RetornoPagamento retornoPagamento = new RetornoPagamento();
            tb_pes_pessoa pessoa = (tb_pes_pessoa)HttpContext.Current.Session["usuario"];

            tb_ped_pedido pedido = new tb_ped_pedido();
            tb_end_endereco enderecoEntrega;

            pedido.ped_dat_criacao = DateTime.Now;
            pedido.ped_num_ip_pedido = HttpContext.Current.Request.UserHostAddress;
            pedido.ped_vlr_frete = Carrinho.Instance.Frete;


            pedido.ped_vlr_total_pedido = Carrinho.Instance.Total;
            //pedido.ped_vlr_total_pedido = new decimal(0.20);
            pedido.tb_ipe_item_pedido = Carrinho.Instance.Items;
            pedido.pes_idt_pessoa = pessoa.pes_idt_pessoa;
            pedido.tb_pes_pessoa = pessoa;

            pedido.tb_tpa_tipo_pagamento = PedidoModel.Instance.ObterFormaPagamento(Carrinho.Instance.FormaPagamento);
            pedido.tpa_idt_tipo_pagamento = pedido.tb_tpa_tipo_pagamento.tpa_idt_tipo_pagamento;

            if (Carrinho.Instance.Cupom != null)
            {
                pedido.tb_cup_cupom = CupomModel.Instance.Obter(Carrinho.Instance.Cupom.cup_idt_cupom);
                pedido.cup_idt_cupom = pedido.tb_cup_cupom.cup_idt_cupom;
            }

            tb_ien_informacao_envio ien = new tb_ien_informacao_envio();
            ien.end_idt_endereco = Carrinho.Instance.IdentificadorEndereco;
            ien.ien_dat_criacao = DateTime.Now;
            ien.tra_idt_transportadora = Carrinho.Instance.Transportadora.tra_idt_transportadora;

            enderecoEntrega = EnderecoModel.Instance.Obter(ien.end_idt_endereco);

            pedido.tb_ien_informacao_envio.Add(ien);

            PedidoModel.Instance.Inserir(pedido);
            HttpContext.Current.Session["pedido"] = pedido;
            retornoPagamento.numeroPedido = pedido.ped_idt_pedido;

            var statusPedido = new tb_spl_status_pedido_log();
            statusPedido.spl_dat_criacao = DateTime.Now;

            var statusPagamento = new tb_spal_status_pagamento_log();
            statusPagamento.spal_dat_criacao = DateTime.Now;

            retornoPagamento.codigoTipoPagamento = pedido.tb_tpa_tipo_pagamento.tpa_cod_tipo_pagamento;

            if (pedido.tb_tpa_tipo_pagamento.tpa_cod_tipo_pagamento.Equals("MAS") || pedido.tb_tpa_tipo_pagamento.tpa_cod_tipo_pagamento.Equals("VIS") || pedido.tb_tpa_tipo_pagamento.tpa_cod_tipo_pagamento.Equals("DIN"))
            {
                Carrinho.Instance.DadosCartaoCredito.NumeroPedidoEstabelecimento = pedido.ped_idt_pedido.ToString();
                try
                {
                    PagamentoRedecard pagamentoRedecard = new PagamentoRedecard();
                    ERetornoPagamento eRetornoPagamento = pagamentoRedecard.EfetuarPagamento(Carrinho.Instance.DadosCartaoCredito, pessoa.pes_idt_pessoa.ToString());

                    //Insere o status do pedido
                    statusPedido.spe_idt_status_pedido = PedidoModel.Instance.ObterStatusPedido("PRO").spe_idt_status_pedido;
                    statusPedido.ped_idt_pedido = pedido.ped_idt_pedido;
                    statusPedido.pes_idt_pessoa = pessoa.pes_idt_pessoa;
                    PedidoModel.Instance.InserirStatus(statusPedido);

                    //Insere o status do pagamento
                    statusPagamento.ped_idt_pedido = pedido.ped_idt_pedido;
                    statusPagamento.spp_idt_status_pagamento_pedido = PedidoModel.Instance.ObterStatusPagamento("AUT").spp_idt_status_pagamento_pedido;
                    PedidoModel.Instance.InserirStatusPagamento(statusPagamento);

                    //Gera o log do pedido
                    var log = new tb_lrp_log_rastreamento_pedido();
                    log.lrp_dat_criacao = DateTime.Now;
                    log.lrp_des_log_rastreio_pedido = "Pedido processado junto a operadora.";
                    log.ped_idt_pedido = retornoPagamento.numeroPedido;
                    PedidoModel.Instance.InserirLogPedido(log);

                    PedidoModel.Instance.AtualizarNumeroAutorizacao(pedido.ped_idt_pedido, eRetornoPagamento.NumeroAutorizacao);
                }
                catch (PagamentoRedecardException pre)
                {
                    //Gera o log do pedido
                    var log = new tb_lrp_log_rastreamento_pedido();
                    log.lrp_dat_criacao = DateTime.Now;
                    log.lrp_des_log_rastreio_pedido = "Pedido não processado junto a operadora.";
                    log.ped_idt_pedido = retornoPagamento.numeroPedido;
                    PedidoModel.Instance.InserirLogPedido(log);
                    
                    statusPedido.spe_idt_status_pedido = PedidoModel.Instance.ObterStatusPedido("CAN").spe_idt_status_pedido;
                    statusPedido.ped_idt_pedido = pedido.ped_idt_pedido;
                    statusPedido.pes_idt_pessoa = pessoa.pes_idt_pessoa;
                    PedidoModel.Instance.InserirStatus(statusPedido);

                    statusPagamento.ped_idt_pedido = pedido.ped_idt_pedido;
                    statusPagamento.spp_idt_status_pagamento_pedido = PedidoModel.Instance.ObterStatusPagamento("ANU").spp_idt_status_pagamento_pedido;
                    PedidoModel.Instance.InserirStatusPagamento(statusPagamento);

                    retornoPagamento.codigoErro = pre.CodigoErro;
                    retornoPagamento.mensagemErro = pre.Message;

                    new Email().TransacaoCartaoCreditoNaoConcluida(pedido.tb_pes_pessoa.pes_des_login, pedido);

                    return retornoPagamento;
                }
                catch (Exception ex)
                {
                    statusPedido.spe_idt_status_pedido = PedidoModel.Instance.ObterStatusPedido("CAN").spe_idt_status_pedido;
                    statusPedido.ped_idt_pedido = pedido.ped_idt_pedido;
                    statusPedido.pes_idt_pessoa = pessoa.pes_idt_pessoa;
                    PedidoModel.Instance.InserirStatus(statusPedido);

                    statusPagamento.ped_idt_pedido = pedido.ped_idt_pedido;
                    statusPagamento.spp_idt_status_pagamento_pedido = PedidoModel.Instance.ObterStatusPagamento("ANU").spp_idt_status_pagamento_pedido;
                    PedidoModel.Instance.InserirStatusPagamento(statusPagamento);

                    retornoPagamento.codigoErro = 99;
                    retornoPagamento.mensagemErro = ex.Message;
                    return retornoPagamento;
                }
            }
            else if (pedido.tb_tpa_tipo_pagamento.tpa_cod_tipo_pagamento.Equals("BOL"))
            {
                //Insere o status do pedido
                statusPedido.spe_idt_status_pedido = PedidoModel.Instance.ObterStatusPedido("PEN").spe_idt_status_pedido;
                statusPedido.ped_idt_pedido = pedido.ped_idt_pedido;
                statusPedido.pes_idt_pessoa = pessoa.pes_idt_pessoa;
                PedidoModel.Instance.InserirStatus(statusPedido);

                //Insere o status do pagamento
                statusPagamento.ped_idt_pedido = pedido.ped_idt_pedido;
                statusPagamento.spp_idt_status_pagamento_pedido = PedidoModel.Instance.ObterStatusPagamento("PEN").spp_idt_status_pagamento_pedido;
                PedidoModel.Instance.InserirStatusPagamento(statusPagamento);

                //Gera o log do pedido
                var log = new tb_lrp_log_rastreamento_pedido();
                log.lrp_dat_criacao = DateTime.Now;
                log.lrp_des_log_rastreio_pedido = "Boleto gerado com sucesso.";
                log.ped_idt_pedido = retornoPagamento.numeroPedido;
                PedidoModel.Instance.InserirLogPedido(log);

                pedido.tb_ien_informacao_envio.First().tb_end_endereco = enderecoEntrega;
                pedido.tb_pes_pessoa = pessoa;

                string urlBoleto = string.Empty;
                string nome, documento;
                nome = documento = string.Empty;
                if (pedido.tb_pes_pessoa.tb_pfi_pessoa_fisica != null)
                {
                    nome = pedido.tb_pes_pessoa.tb_pfi_pessoa_fisica.pfi_nom_pessoa_fisica;
                    documento = pedido.tb_pes_pessoa.tb_pfi_pessoa_fisica.pfi_num_cpf;
                }
                else if (pedido.tb_pes_pessoa.tb_pju_pessoa_juridica != null)
                {
                    nome = pedido.tb_pes_pessoa.tb_pju_pessoa_juridica.pju_des_razao_social;
                    documento = pedido.tb_pes_pessoa.tb_pju_pessoa_juridica.pju_num_cnpj;
                }

                GerarBoleto gr = new GerarBoleto();
                urlBoleto = gr.GerarBoletoHSBC(pedido.ped_idt_pedido, nome, documento, pedido.ped_vlr_total_pedido.Value);

                retornoPagamento.codigoErro = 0;
                retornoPagamento.mensagemErro = urlBoleto;
                retornoPagamento.numeroPedido = pedido.ped_idt_pedido;
                retornoPagamento.codigoTipoPagamento = "BOL";

                HttpContext.Current.Session["urlBoleto"] = urlBoleto;
            }
            else if (pedido.tb_tpa_tipo_pagamento.tpa_cod_tipo_pagamento.Equals("DEB"))
            {
                //Insere o status do pedido
                statusPedido.spe_idt_status_pedido = PedidoModel.Instance.ObterStatusPedido("PEN").spe_idt_status_pedido;
                statusPedido.ped_idt_pedido = pedido.ped_idt_pedido;
                statusPedido.pes_idt_pessoa = pessoa.pes_idt_pessoa;
                PedidoModel.Instance.InserirStatus(statusPedido);

                //Insere o status do pagamento
                statusPagamento.ped_idt_pedido = pedido.ped_idt_pedido;
                statusPagamento.spp_idt_status_pagamento_pedido = PedidoModel.Instance.ObterStatusPagamento("PEN").spp_idt_status_pagamento_pedido;
                PedidoModel.Instance.InserirStatusPagamento(statusPagamento);

                retornoPagamento.codigoErro = 0;
                retornoPagamento.mensagemErro = string.Empty;
                retornoPagamento.numeroPedido = pedido.ped_idt_pedido;
                retornoPagamento.codigoTipoPagamento = "DEB";
            }

            try
            {
                //TODO: COLOCAR O EMAIL Q RECEBERÁ ENTRADA DE PEDIDOS
                new Email().PedidoIncluido(pedido.tb_pes_pessoa.pes_des_login, pedido);
            }
            catch (Exception ex)
            {
                //TODO: Validar as Exceptions
                //throw ex;
            }

            Carrinho.Instance.Limpar();

            return retornoPagamento;
        }

        private static string PostGateway(string requisicao, string url)
        {
            string responseText;
            var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.ContentType = "text/json";
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
            {
                streamWriter.Write(requisicao);
            }

            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                responseText = streamReader.ReadToEnd();
            }

            return responseText;
        }
    }
}